#include "TcpConnection.h"
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

TcpConnection::TcpConnection(int fd)
: _sockIO(fd)
, _sock(fd)
, _localAddr(getLocalAddr())
, _peerAddr(getPeerAddr())
{

}

TcpConnection::~TcpConnection()
{

}

string TcpConnection::receive()
{
    char buf[655536] = {0};
    _sockIO.readLine(buf, sizeof(buf));
    return string(buf);
}

void TcpConnection::send(const string &msg)
{
    _sockIO.writen(msg.c_str(), msg.size());
}

void TcpConnection::toString()
{
    cout << _localAddr.ip() << ":" << _localAddr.port()
        << " -------> " << _peerAddr.ip() << ":" << _peerAddr.port();
}

InetAddress TcpConnection::getLocalAddr()
{
    struct sockaddr_in localaddr;
    socklen_t len = sizeof(localaddr);
    int ret = getsockname(_sock.fd(), (struct sockaddr*)&localaddr, &len);
    if(ret == -1)
    {
        perror("getsockname");
    }
    return InetAddress(localaddr);
}

InetAddress TcpConnection::getPeerAddr()
{
    struct sockaddr_in peeraddr;
    socklen_t len = sizeof(peeraddr);
    int ret = getpeername(_sock.fd(), (struct sockaddr*)&peeraddr, &len);
    if(ret == -1)
    {
        perror("getpeername");
    }
    return InetAddress(peeraddr);
}

void TcpConnection::setNewConnectionCallback(const TcpConnectionCallback &cb)
{
    _onNewConnection = cb;
}

void TcpConnection::setMessageCallback(const TcpConnectionCallback &cb)
{
    _onMessage = cb;
}

void TcpConnection::setCloseCallback(const TcpConnectionCallback &cb)
{
    _onClose = cb;
}

void TcpConnection::handleNewConnectionCallback()
{
    if(_onNewConnection)
    {
        _onNewConnection(shared_from_this());
    }
    else
    {
        cout << "_onNewConnection == nullptr" << endl;
    }
}

void TcpConnection::handleMessageCallback()
{
    if(_onMessage)
    {
        _onMessage(shared_from_this());
    }
    else
    {
        cout << "_onMessage == nullptr" << endl;
    }
}

void TcpConnection::handleCloseCallback()
{
    if(_onClose)
    {
        _onClose(shared_from_this());
    }
    else
    {
        cout << "_onClose == nullptr" << endl;
    }
}

bool TcpConnection::isClose() const
{
    char buf[16];
    int ret = recv(_sock.fd(), buf, sizeof(buf), MSG_PEEK);
    return (ret == 0);
}

